<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-model</title>
</head>
<body>
<div id="app">
    <input type="text" v-model="name" style="width: 100%;" />
    <p v-text="name"></p>
    <script>
        let data = {
            name: '李云龙',
            age: 17
        }
        // 把data中的属性变成响应式的
        Object.keys(data).forEach((key) => {
            defineReactive(data, key, data[key])
        })
        function defineReactive(data, key, value) {
            // 进行转换操作
            Object.defineProperty(data, key, {
                get() {
                    console.log('您访问了属性', key)
                    return value
                },
                set(newValue) {
                    // set函数的执行 不会自动判断俩次修改的值是否相等
                    // 显然如果相等 不应该执行变化的逻辑
                    if (newValue === value) {
                        return
                    }
                    console.log('您修改了属性', key)
                    value = newValue
                    // 这里我们把最新的值 反映到视图中  这里是关键的位置
                    // 核心：操作dom  就是通过操作dom api 把最新的值设置上去
                    compile()
                }
            })
        }
        // 1.通过标识查找把数据放到对应的dom上显示出来
        function compile() {
            console.log("compile")
            let app = document.getElementById('app')
            // 拿到所有节点
            const childNodes = app.childNodes // 所有类型的节点包括文本节点和标签节点
            console.log(childNodes)
            // 刷选出来目标节点 -> p
            childNodes.forEach(node => {
                // console.log("node.nodeType",node.nodeType)
                if (node.nodeType === 1) {
                    // 这里拿到的是标签节点
                    console.log("node", node)
                    // 刷选v-text属性 p id class (v-text)
                    // 拿到所有的标签属性
                    const attrs = node.attributes
                    console.log("attrs", attrs)
                    Array.from(attrs).forEach(attr => {
                        console.log(attr)
                        const nodeName = attr.nodeName
                        const nodeValue = attr.nodeValue
                        console.log(nodeName, nodeValue)
                        // 实现v-model
                        if (nodeName === 'v-model') {
/*                            setTimeout(()=>{
                                // 调用dom操作给input标签绑定数据
                                node.value = data[nodeValue]
                                // 监听input事件 在事件回调中 拿到最新的输入值 赋值给绑定的属性
                                node.addEventListener('input', (e) => {
                                    let newValue = e.target.value
                                    // 反向赋值
                                    data[nodeValue] = newValue
                                })
                            }, 0)*/
                            // 调用dom操作给input标签绑定数据
                            node.value = data[nodeValue]
                            // 监听input事件 在事件回调中 拿到最新的输入值 赋值给绑定的属性
                            node.addEventListener('input', (e) => {
                                let newValue = e.target.value
                                // 反向赋值
                                data[nodeValue] = newValue
                            })

                        }
                        if (nodeName === 'v-text') {
                            node.innerText = data[nodeValue]
                        }
                    })
                }
            })
        }
        compile()
    </script>
</body>
</html>
